package com.xmy.cultivate.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.xmy.cultivate.entity.*;
import com.xmy.cultivate.entity.response.EnrollRanking;
import com.xmy.cultivate.entity.response.EnrollSubjectRanking;
import com.xmy.cultivate.entity.response.EnrollTeamRanking;
import com.xmy.cultivate.entity.views.EnrollDetail;
import com.xmy.cultivate.mapper.*;
import com.xmy.cultivate.service.IEnrollInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xmy.cultivate.service.IStaffService;
import com.xmy.cultivate.util.CommonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * <p>
 * 招生数据 服务实现类
 * </p>
 *
 * @author min
 * @since 2023-02-10
 */
@Service
public class EnrollInfoServiceImpl extends ServiceImpl<EnrollInfoMapper, EnrollInfo> implements IEnrollInfoService {


    @Autowired
    @Lazy
    IStaffService iStaffService;

    @Autowired
    EnrollInfoMapper enrollInfoMapper;

    @Autowired
    EnrollTeamMapper enrollTeamMapper;

    @Autowired
    EnrollTeamMemberMapper enrollTeamMemberMapper;

    @Autowired
    StaffMapper staffMapper;

    @Autowired
    OrganizationMapper organizationMapper;

    @Autowired
    StudentMapper studentMapper;

    @Autowired
    SubjectsMapper subjectsMapper;

    @Autowired
    OrderApplyMapper orderApplyMapper;

    @Autowired
    OrderDetailMapper orderDetailMapper;

    @Autowired
    GradeMapper gradeMapper;

    @Autowired
    DictMapper dictMapper;

    public List<EnrollRanking> rankingList(String type, String startDate, String endDate, String schoolId, String subjectsId, String trackId) {
        List<EnrollRanking> enrollRankingList = new ArrayList<>();

        List<Staff> staffList;
        if (StringUtils.isEmpty(trackId)) {
            staffList = iStaffService.getEnrollMemberList(startDate, endDate);
        } else {
            QueryWrapper<Staff> staffQueryWrapper = new QueryWrapper<>();
            staffQueryWrapper.inSql("id", "select sourse_id from track_detail where deleted=0 and track_id = " + trackId + "");
            staffList = staffMapper.selectList(staffQueryWrapper);
        }

        EnrollRanking enrollRanking;


        for (Staff staff : staffList) {
            enrollRanking = new EnrollRanking();
            enrollRanking.setTeacherName(staff.getName());

            //总数
            Integer dealNumType = 1;
            BigDecimal allCount = this.getDealNum(staff.getId(), type, dealNumType, startDate, endDate, schoolId, subjectsId, null);
            enrollRanking.setAllCount(allCount);

            //退费数
            dealNumType = 2;
            BigDecimal returnCount = this.getDealNum(staff.getId(), type, dealNumType, startDate, endDate, schoolId, subjectsId, null);
            enrollRanking.setReturnCount(returnCount);

            //今日新增
            dealNumType = 3;
            BigDecimal dateNewly = this.getDealNum(staff.getId(), type, dealNumType, startDate, endDate, schoolId, subjectsId, null);
            enrollRanking.setDateNewly(dateNewly);

            enrollRankingList.add(enrollRanking);
        }

        return enrollRankingList;
    }

    /**
     * 收入排行
     *
     * @param type
     * @param startDate
     * @param endDate
     * @param schoolId
     * @param subjectsId
     * @return
     */
    public List<EnrollRanking> incomeRankingList(String type, String startDate, String endDate, String schoolId, String subjectsId) {
        List<EnrollRanking> enrollRankingList = new ArrayList<>();
        List<Staff> staffList = iStaffService.getEnrollMemberList(startDate, endDate);
        EnrollRanking enrollRanking;


        for (Staff staff : staffList) {
            enrollRanking = new EnrollRanking();
            enrollRanking.setTeacherName(staff.getName());

            //总数
            Integer dealNumType = 1;
            BigDecimal allCount = this.getDealMoney(staff.getId(), type, dealNumType, startDate, endDate);
            enrollRanking.setAllCount(allCount);

            //今日新增
            dealNumType = 3;
            BigDecimal dateNewly = this.getDealMoney(staff.getId(), type, dealNumType, startDate, endDate);
            enrollRanking.setDateNewly(dateNewly);

            enrollRankingList.add(enrollRanking);
        }

        return enrollRankingList;
    }

    public List<EnrollTeamRanking> teamRankingList(String startDate, String endDate, String schoolId) {

        List<EnrollTeamRanking> enrollTeamRankingList = new ArrayList<>();

        List<EnrollTeam> enrollTeamList = enrollTeamMapper.selectList(new QueryWrapper<EnrollTeam>().eq("status", 1).eq("deleted", 0));
        for (EnrollTeam enrollTeam : enrollTeamList) {

            EnrollTeamRanking enrollTeamRanking = new EnrollTeamRanking();
            enrollTeamRanking.setName(enrollTeam.getName());
            enrollTeamRanking.setId(enrollTeam.getId());
            BigDecimal inviteCount = this.getTeamDealNum(enrollTeam.getId(), 1, 1, startDate, endDate);
            enrollTeamRanking.setInviteCount(inviteCount);
            BigDecimal auditionCount = this.getTeamDealNum(enrollTeam.getId(), 2, 2, startDate, endDate);
            enrollTeamRanking.setAuditionCount(auditionCount);
            BigDecimal bargainCount = this.getTeamDealNum(enrollTeam.getId(), 3, 3, startDate, endDate);
            enrollTeamRanking.setBargainCount(bargainCount);

            enrollTeamRankingList.add(enrollTeamRanking);
        }
        return enrollTeamRankingList;
    }

    @Override
    public List<EnrollSubjectRanking> subjectRankingList(String startDate, String endDate, String schoolId) {

        List<EnrollSubjectRanking> enrollSubjectRankingList = new ArrayList<>();

        QueryWrapper<EnrollTeam> enrollTeamQueryWrapper = new QueryWrapper<>();
        enrollTeamQueryWrapper.eq("status", 1);
        enrollTeamQueryWrapper.eq("deleted", 0);

        List<EnrollTeam> enrollTeamList = enrollTeamMapper.selectList(enrollTeamQueryWrapper);

        for (EnrollTeam enrollTeam : enrollTeamList) {
            EnrollSubjectRanking enrollSubjectRanking = new EnrollSubjectRanking();
            enrollSubjectRanking.setName(enrollTeam.getName());

            BigDecimal englishCount = this.getSubjectDealNum(enrollTeam.getId(), 1, 1, startDate, endDate);
            enrollSubjectRanking.setEnglishCount(englishCount);
            BigDecimal mathCount = this.getSubjectDealNum(enrollTeam.getId(), 2, 1, startDate, endDate);
            enrollSubjectRanking.setMathCount(mathCount);
            BigDecimal physicsCount = this.getSubjectDealNum(enrollTeam.getId(), 3, 1, startDate, endDate);
            enrollSubjectRanking.setPhysicsCount(physicsCount);
            enrollSubjectRankingList.add(enrollSubjectRanking);
        }

        return enrollSubjectRankingList;
    }

    /**
     * 获取教师数量
     *
     * @param teacherId
     * @param type        1、邀约，2、试听，3、成交
     * @param dealNumType 1、正常数量，2、退费，3、今日新增
     * @param startDate
     * @param endDate
     * @param schoolId
     * @param subjectsId
     * @return
     */
    private BigDecimal getDealNum(Long teacherId, String type, Integer dealNumType, String startDate, String endDate, String schoolId, String subjectsId, Long teamId) {
        QueryWrapper<EnrollInfo> enrollInfoQueryWrapper = new QueryWrapper<>();

        if (dealNumType.equals(3)) {
            enrollInfoQueryWrapper.eq("add_date", LocalDate.now());//今日新增
        } else {
            if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
                enrollInfoQueryWrapper.between("add_date", LocalDate.parse(startDate), LocalDate.parse(endDate));
            } else if (StringUtils.isNotBlank(startDate)) {
                enrollInfoQueryWrapper.ge("add_date", LocalDate.parse(startDate));
            } else if (StringUtils.isNotBlank(endDate)) {
                enrollInfoQueryWrapper.le("add_date", LocalDate.parse(endDate));
            }
        }

        if (teamId != null) {
            enrollInfoQueryWrapper.eq("team_id", teamId);
        }

        //退费
        if (dealNumType.equals(2)) {
            enrollInfoQueryWrapper.eq("is_return", 1);
        }

        enrollInfoQueryWrapper.eq("type", type);//类型：邀约:1，试听:2，成交:3

        enrollInfoQueryWrapper.eq("teacher_id", teacherId);
        enrollInfoQueryWrapper.eq("deleted", 0);

        return enrollInfoMapper.getDealNum(enrollInfoQueryWrapper);
    }

    private BigDecimal getDealMoney(Long teacherId, String type, Integer dealNumType, String startDate, String endDate) {
        QueryWrapper<EnrollInfo> enrollInfoQueryWrapper = new QueryWrapper<>();

        if (dealNumType.equals(3)) {
            enrollInfoQueryWrapper.eq("add_date", LocalDate.now());//今日新增
        } else {
            if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
                enrollInfoQueryWrapper.between("add_date", LocalDate.parse(startDate), LocalDate.parse(endDate));
            } else if (StringUtils.isNotBlank(startDate)) {
                enrollInfoQueryWrapper.ge("add_date", LocalDate.parse(startDate));
            } else if (StringUtils.isNotBlank(endDate)) {
                enrollInfoQueryWrapper.le("add_date", LocalDate.parse(endDate));
            }
        }

        enrollInfoQueryWrapper.eq(StringUtils.isNotBlank(type), "type", type);//类型：邀约:1，试听:2，成交:3

        enrollInfoQueryWrapper.eq("teacher_id", teacherId);
        enrollInfoQueryWrapper.eq("deleted", 0);

        return enrollInfoMapper.getDealMoney(enrollInfoQueryWrapper);
    }

    /**
     * 战队科目数量
     *
     * @param teamId
     * @param subjectType
     * @param type
     * @param startDate
     * @param endDate
     * @return
     */
    private BigDecimal getSubjectDealNum(Long teamId, Integer subjectType, Integer type, String startDate, String endDate) {
        QueryWrapper<EnrollInfo> enrollInfoQueryWrapper = new QueryWrapper<>();

        if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
            enrollInfoQueryWrapper.between("add_date", LocalDate.parse(startDate), LocalDate.parse(endDate));
        } else if (StringUtils.isNotBlank(startDate)) {
            enrollInfoQueryWrapper.ge("add_date", LocalDate.parse(startDate));
        } else if (StringUtils.isNotBlank(endDate)) {
            enrollInfoQueryWrapper.le("add_date", LocalDate.parse(endDate));
        }

        enrollInfoQueryWrapper.eq("type", type);//类型：邀约:1，试听:2，成交:3

        enrollInfoQueryWrapper.eq("subjects_id", subjectType);
        enrollInfoQueryWrapper.eq("deleted", 0);

        enrollInfoQueryWrapper.eq("team_id", teamId);

        return enrollInfoMapper.getDealNum(enrollInfoQueryWrapper);
    }

    /**
     * 战队数量
     *
     * @param teamId
     * @param subjectType
     * @param type
     * @param startDate
     * @param endDate
     * @return
     */
    private BigDecimal getTeamDealNum(Long teamId, Integer subjectType, Integer type, String startDate, String endDate) {
        QueryWrapper<EnrollInfo> enrollInfoQueryWrapper = new QueryWrapper<>();

        if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
            enrollInfoQueryWrapper.between("add_date", LocalDate.parse(startDate), LocalDate.parse(endDate));
        } else if (StringUtils.isNotBlank(startDate)) {
            enrollInfoQueryWrapper.ge("add_date", LocalDate.parse(startDate));
        } else if (StringUtils.isNotBlank(endDate)) {
            enrollInfoQueryWrapper.le("add_date", LocalDate.parse(endDate));
        }

        enrollInfoQueryWrapper.eq("type", type);//类型：邀约:1，试听:2，成交:3

        //enrollInfoQueryWrapper.eq("subjects_id",subjectType);
        enrollInfoQueryWrapper.eq("deleted", 0);

        //enrollInfoQueryWrapper.inSql("teacher_id","select teacher_id from enroll_team_member where team_id ="+teamId+" and status=1");

        enrollInfoQueryWrapper.eq("team_id", teamId);

        return enrollInfoMapper.getDealNum(enrollInfoQueryWrapper);
    }


    public List<EnrollTeamRanking> teamRankingDetail(String teamId, String startDate, String endDate, String schoolId) {

        QueryWrapper<EnrollTeamMember> enrollTeamMemberQueryWrapper = new QueryWrapper<>();
        enrollTeamMemberQueryWrapper.eq("team_id", teamId);
        enrollTeamMemberQueryWrapper.eq("deleted", 0);

        List<EnrollTeamMember> enrollTeamMemberList = enrollTeamMemberMapper.selectList(enrollTeamMemberQueryWrapper);

        List<EnrollTeamRanking> enrollTeamRankingList = new ArrayList<>();

        for (EnrollTeamMember enrollTeamMember : enrollTeamMemberList) {

            EnrollTeamRanking enrollTeamRanking = new EnrollTeamRanking();

            Staff staff = staffMapper.selectById(enrollTeamMember.getTeacherId());
            if (staff != null) {
                enrollTeamRanking.setName(staff.getName());
            }

            BigDecimal inviteCount = this.getDealNum(enrollTeamMember.getTeacherId(), "1", 1, startDate, endDate, schoolId, "", enrollTeamMember.getTeamId());
            enrollTeamRanking.setInviteCount(inviteCount);
            BigDecimal auditionCount = this.getDealNum(enrollTeamMember.getTeacherId(), "2", 1, startDate, endDate, schoolId, "", enrollTeamMember.getTeamId());
            enrollTeamRanking.setAuditionCount(auditionCount);
            BigDecimal bargainCount = this.getDealNum(enrollTeamMember.getTeacherId(), "3", 1, startDate, endDate, schoolId, "", enrollTeamMember.getTeamId());
            enrollTeamRanking.setBargainCount(bargainCount);

            BigDecimal returnCount = this.getDealNum(enrollTeamMember.getTeacherId(), "3", 2, startDate, endDate, schoolId, "", enrollTeamMember.getTeamId());
            enrollTeamRanking.setReturnCount(returnCount);
            enrollTeamRankingList.add(enrollTeamRanking);

        }

        return enrollTeamRankingList;
    }

    /**
     * 个人数据
     *
     * @param teacherId
     * @param startDate
     * @param endDate
     * @return
     */
    public EnrollTeamRanking personData(Long teacherId, String startDate, String endDate) {

        EnrollTeamRanking enrollTeamRanking = new EnrollTeamRanking();

        BigDecimal inviteCount = this.getDealNum(teacherId, "1", 1, startDate, endDate, null, null, null);
        enrollTeamRanking.setInviteCount(inviteCount);
        BigDecimal auditionCount = this.getDealNum(teacherId, "2", 1, startDate, endDate, null, null, null);
        enrollTeamRanking.setAuditionCount(auditionCount);
        BigDecimal bargainCount = this.getDealNum(teacherId, "3", 1, startDate, endDate, null, null, null);
        enrollTeamRanking.setBargainCount(bargainCount);
        BigDecimal deductMoney = this.getDealMoney(teacherId, "", 1, startDate, endDate);
        enrollTeamRanking.setDeductMoney(deductMoney);

        return enrollTeamRanking;
    }

    public List<EnrollRanking> regetRanking(List<EnrollRanking> enrollRankingList, int sortType) {
        //Sort the list using the comparator
        Comparator<EnrollRanking> allCountComparator = (EnrollRanking o2, EnrollRanking o1) -> {
            int result;
            if (o1.getAllCount().equals(o2.getAllCount())) {
                result = 0;
            } else {
                result = o1.getAllCount().compareTo(o2.getAllCount());
            }
            return result;
        };
        Comparator<EnrollRanking> returnCountComparator = (EnrollRanking o2, EnrollRanking o1) -> {
            int result;
            if (o1.getReturnCount().equals(o2.getReturnCount())) {
                result = 0;
            } else {
                result = o1.getReturnCount().compareTo(o2.getReturnCount());
            }
            return result;
        };
        Comparator<EnrollRanking> dateNewlyComparator = (EnrollRanking o2, EnrollRanking o1) -> {
            int result;
            if (o1.getDateNewly().equals(o2.getDateNewly())) {
                result = 0;
            } else {
                result = o1.getDateNewly().compareTo(o2.getDateNewly());
            }
            return result;
        };

        //Add the ranking values to the list
        if (sortType == 1) {
            Collections.sort(enrollRankingList, allCountComparator);
            int ranking = 1;
            int rank = 1;
            BigDecimal allCount = null;
            for (EnrollRanking er : enrollRankingList) {
                if (allCount == null) {
                    allCount = er.getAllCount();
                    er.setRanking(ranking);
                }
                if (er.getAllCount().equals(allCount)) {
                } else {
                    ranking = rank;
                }
                er.setRanking(ranking);
                rank++;
                allCount = er.getAllCount();
            }
        } else if (sortType == 2) {
            Collections.sort(enrollRankingList, returnCountComparator);
            int ranking = 1;
            int rank = 1;
            BigDecimal returnCount = null;
            for (EnrollRanking er : enrollRankingList) {
                if (returnCount == null) {
                    returnCount = er.getReturnCount();
                    er.setRanking(ranking);
                }
                if (er.getReturnCount().equals(returnCount)) {
                } else {
                    ranking = rank;
                }
                er.setRanking(ranking);
                rank++;
                returnCount = er.getReturnCount();
            }
        } else if (sortType == 3) {
            Collections.sort(enrollRankingList, dateNewlyComparator);
            int ranking = 1;
            int rank = 1;
            BigDecimal dateNewly = null;
            for (EnrollRanking er : enrollRankingList) {
                if (dateNewly == null) {
                    dateNewly = er.getDateNewly();
                    er.setRanking(ranking);
                }
                if (er.getDateNewly().equals(dateNewly)) {
                } else {
                    ranking = rank;
                }
                er.setRanking(ranking);
                rank++;
                dateNewly = er.getDateNewly();
            }
        }
        return enrollRankingList;
    }

    public List<SchoolNewStudent> schoolNewData(QueryWrapper queryWrapper) {
        List<SchoolNewStudent> schoolNewStudents = enrollInfoMapper.schoolNewData(queryWrapper);
        for (SchoolNewStudent schoolNewStudent : schoolNewStudents) {
            schoolNewStudent.setName(organizationMapper.getSchoolName(Long.parseLong(schoolNewStudent.getSchoolId())));
        }
        return schoolNewStudents;
    }

    /**
     * 招生核对率
     */
    public IPage<EnrollDetail> getParticularsRate(IPage<?> page, String schoolId, String subjectsId, String startDate, String endDate, String checkType, String studentName, String teacherName, String yearClassId, String yearPart, String quarterNum, String isTrueData, String type, Integer isDetails) {
        QueryWrapper<EnrollInfo> wrapper = new QueryWrapper<>();
        List<String> groupBy = new ArrayList<>();

        if(isDetails == 0){
            // 列表
            if ("1".equals(type)) {
                groupBy.add("teacher_id");
            }
            if ("2".equals(type)) {
                groupBy.add("school_id,teacher_id");
            }
            if ("3".equals(type)) {
                wrapper.apply("teacher_id in(select admin_id from role_admin where role_id = 1568160887369994242)");
                groupBy.add("teacher_id");
            }
            if ("4".equals(type)) {
                groupBy.add("school_id");
            }
            wrapper.orderByDesc("order_id,teacher_id");
        }else if(isDetails == 1){
            // 详情
            groupBy.add("id");
            wrapper.orderByDesc("order_id,student_id");
        }

        wrapper.groupBy(groupBy);

        wrapper.eq("deleted", 0);
        // 为了和招生端的一致，先将年份和年级去掉（招生没有传年份学期，只有日期）2024-09-26
//        wrapper.eq(StringUtils.isNotBlank(yearPart), "year_part", yearPart);
//        wrapper.eq(StringUtils.isNotBlank(quarterNum), "quarter_num", quarterNum);
        wrapper.eq(StringUtils.isNotBlank(yearClassId), "year_class_id", yearClassId);
        wrapper.inSql(StringUtils.isNotBlank(schoolId), "school_id", schoolId);
        wrapper.eq(StringUtils.isNotBlank(subjectsId), "subjects_id", subjectsId);
        wrapper.eq(StringUtils.isNotBlank(isTrueData), "is_true", isTrueData);
        wrapper.eq(StringUtils.isNotBlank(checkType), "check_type", checkType);

        if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
            wrapper.between("add_date", startDate, endDate);
        } else if (StringUtils.isNotBlank(startDate)) {
            wrapper.eq("add_date", startDate);
        } else if (StringUtils.isNotBlank(endDate)) {
            wrapper.eq("add_date", endDate);
        }

        wrapper.inSql(StringUtils.isNotBlank(studentName), "student_id", "select id from student where name like '%" + studentName + "%'");
        wrapper.inSql(StringUtils.isNotBlank(teacherName), "teacher_id", "select id from staff where name like '%" + teacherName + "%'");

        IPage<EnrollDetail> enrollDetails = enrollInfoMapper.getParticularsRate(page, wrapper);
        //邀约:1，试听:2，成交:3
        String[] typeArr = {"", "邀约", "试听", "成交", "号码"};
        for (EnrollDetail enrollDetail : enrollDetails.getRecords()) {
            enrollDetail.setTypeName(typeArr[enrollDetail.getType()]);
            Student student = studentMapper.selectById(enrollDetail.getStudentId());
            if (student != null) {
                enrollDetail.setStudentName(student.getName());
            }
            Subjects subjects = subjectsMapper.selectById(enrollDetail.getSubjectsId());
            if (subjects != null) {
                enrollDetail.setSubjectsName(subjects.getName());
            }

            enrollDetail.setYearClassName(CommonUtil.getYearClassNameForId(enrollDetail.getYearClassId()));

            Organization organization = organizationMapper.selectById(enrollDetail.getSchoolId());
            if (organization != null) {
                enrollDetail.setSchoolName(organization.getName());
            }
            OrderApply orderApply = orderApplyMapper.selectById(enrollDetail.getOrderId());
            if (orderApply != null) {
                QueryWrapper<OrderDetail> orderDetailQueryWrapper = new QueryWrapper<>();
                orderDetailQueryWrapper.eq("order_id", orderApply.getId());
                orderDetailQueryWrapper.last("limit 1");
                OrderDetail orderDetail = orderDetailMapper.selectOne(orderDetailQueryWrapper);
                if (orderDetail != null) {
                    Grade grade = gradeMapper.selectById(orderDetail.getGradeId());
                    if (grade != null) {
                        QueryWrapper<Dict> dictQueryWrapper = new QueryWrapper<>();
                        dictQueryWrapper.eq("num", grade.getYearClassId());
                        dictQueryWrapper.eq("type", 14);
                        dictQueryWrapper.last("limit 1");
                        Dict dict = dictMapper.selectOne(dictQueryWrapper);
                        if (dict != null) {
                            enrollDetail.setYearClassName(dict.getName());
                        }
                    }
                }
            }
            Staff staff = staffMapper.selectById(enrollDetail.getTeacherId());
            if (staff != null) {
                enrollDetail.setTeacherName(staff.getName());
            }
        }

        return enrollDetails;
    }

}
